///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.rectangular
{
  import flash.events.IEventDispatcher;
  
  import ilog.gauges.gaugesClasses.LinearScale;
  import ilog.gauges.gaugesClasses.rectangular.IRectangularNumericScale;
  
  /**
   * The <code>RectangularLinearScale</code> class represents the linear scale for 
   * rectangular gauges. This class can be used to populate the <i>scales</i> array 
   * of the gauge.
   *  
   * @see ilog.gauges.rectangular.RectangularGauge
   * 
   * @includeExample examples/RectangularGaugeExample.mxml -noswf
   */
  public class RectangularLinearScale extends LinearScale implements IRectangularNumericScale
  {
    /**
     * Constructor
     */
    public function RectangularLinearScale()
    {
    }
   
    private var _offset:Number = 0;

    [Bindable]
    [Inspectable(environment="none")]       

    /**
     *  @copy ilog.gauges.gaugesClasses.rectangular.IRectangularScale#offset
     */
    public function get offset():Number
    {
      return _offset;
    }

    /**
     * @private
     */
    public function set offset(value:Number):void
    {
      if (value != _offset) {
        _offset = value;
        invalidateElements();
      }
    }

    private var _length:Number = 0;

    [Bindable]
    [Inspectable(environment="none")]       

    /**
     *  @copy ilog.gauges.gaugesClasses.rectangular.IRectangularScale#length
     */
    public function get length():Number
    {
      return _length;
    }

    /**
     * @private
     */
    public function set length(value:Number):void
    {
      if (value != _length) {
        _length = value;
        invalidateElements();
      }
    }

    /**
     *  @copy ilog.gauges.gaugesClasses.rectangular.IRectangularScale#positionForValue
     */
    public function positionForValue(value:Object):Number
    {
      var v:Number = value as Number;
      // unsupported values should never go trough this
      if (maximum < minimum || v <= minimum || isNaN(v))
        v = minimum;
      else if (v >= maximum)
        v = maximum;
      return _offset + ((v - minimum) * _length) / (maximum - minimum); 
    }

    /**
     *  @copy ilog.gauges.gaugesClasses.rectangular.IRectangularScale#valueForPosition
     */
    public function valueForPosition(position:Number):Object
    {
      // limit positions, return the extremum
      if (position < _offset)
        return minimum;
      if (position > _offset + _length)
        return maximum;
      var value:Number = minimum + (position - _offset) * (maximum - minimum) / _length;
      if (!isNaN(snapInterval) && snapInterval > 0) {
        value = Math.round((value - minimum) / snapInterval) * snapInterval + minimum;
        if (snapIntervalPrecision != -1) {
          var scale:Number = Math.pow(10, snapIntervalPrecision);
          value = Math.round(value * scale) / scale;
        }
      }
      return value;
    }    
    
    /**
     *  @copy ilog.gauges.gaugesClasses.rectangular.IRectangularScale#positionInRange
     */    
    public function positionInRange(position:Number):Boolean
    {
      return (position >= _offset && position <= _offset + _length);
    }
  }
}
